
var express = require('express');
var env       = process.env.NODE_ENV || "development";
var config = require( '../config/config.json');
var utils = require('../utils/utils');
var router  = express.Router();
var multiparty = require('multiparty');
var fs = require('fs'); 
var gm = require('gm');
var exec = require('child_process').exec; 
var imageMagick = gm.subClass({ imageMagick: true });

router.get('/', function(req, res) {
	
	var font = req.query.font;      // 字体库文件名
	var msg = req.query.msg;          //消息主体
	var color = req.query.color;      //字体颜色
	var jumper = req.query.jumper;     //字体是否跳动（gif）
	var border = req.query.border;     //是否描边
	var star = req.query.star;					//星星特效，暂时没实现
	var id = req.query.id;							//图片id

	if(!color) color='black';
	if(!id) {sendJson(res,{error:'no id'});retrun}
	
	//从内存中读emoticon对象
	var emo = utils.findByPorperty(global.emoticonCache.emoticons,id,'id');
	if(!emo) {sendJson(res,{error:'id error'});retrun}
	var x = emo.x;
	var y = emo.y;
	var fontSize = emo.fontSize;
	var fileName = emo.fileName;
	
	if(!x) x=1
	if(!y) y=1
	if(!fontSize) fontSize=26
	var lineLimit = emo.lineLimit;
	if(!font || !config.fonts[font]){
		font = "tehei";
	}
	var fileType = '.jpg';
	if(fileName.indexOf('.gif') >0) fileType = '.gif';


	//读取../config/config.json定义的图片路径，
	var params = config[env +'Param'];
	
	var date = utils.getDateString(true) +"/"
	var folder = params.temPath + date
	
	//生成临时文件夹，以日期加小时命名
	utils.folderCheck(folder)

	var ttf = params.fontPath+font+'.ttf'
	var tmpFileName = utils.uuid() + fileType;
	
	var tmpFile =  folder+tmpFileName;
	
	var finalName = date + tmpFileName;
	var srcFile = params.srcPath + fileName;
	
	//读取图片宽高
	gm(srcFile).size(function(err, value){
	    	if(err){
					sendJson(res,{error:'size'});
					return;
				}
				var width = value.width
				var height = value.height	
				msg = formateMsg(width,height,msg,fontSize);
	
			if(jumper !='true' && star !='true' && border!='true')
				//加静态文字
				genText(res,srcFile,ttf,fontSize,x,y,msg,color,tmpFile,finalName)
			else if(jumper !='true' && star !='true' && border=='true')
				//静态文字描边
				strokeText(res,srcFile,ttf,fontSize,x,y,msg,color,tmpFile,finalName)
			else{
				
				var  im = imageMagick(srcFile).size(function(err, value){
					//生成gif	
					genGif(res,value,srcFile,ttf,fontSize,x,y,msg,color,tmpFile,finalName,jumper,border,star,fileType)
				})
				
				
			}
	})
              	
});

//post接口，接收视频，并转成gif
router.post('/', function(req, res) { 
	var reqParam = null;
	
	var date = utils.getDateString(true) +"/"
	var params = config[env +'Param'];
	var form = new multiparty.Form();
  form.encoding = 'utf-8';
  form.uploadDir = params.uploadPath + date;
  form.maxFilesSize = 5 * 1024 * 1024;
  
  utils.folderCheck(form.uploadDir)
 
  form.parse(req, function(err, fields, files) {
		if(err){
			sendJson(res,{error:'form.parse'});
			return;
		}
		
    var theFile = files.file[0].path;
    reqParam = fields
    
    var fileType = reqParam.fileType;	
   
    if(fileType == 'img'){
 
	    gm(theFile).size(function(err, value){
	    	if(err){
					sendJson(res,{error:'imgSize'});
					return;
				}
				var width = value.width
				var height = value.height	
				if(width > 400){
					var formateFile = theFile.replace('.','1.')
					var dist = 400;
					if(height > width) dist= 300
					
					var crop=reqParam.crop
					var v = width/height;
					var obj = gm(theFile);
					if(v>1.4){
						if(crop =='bottom') obj = obj.crop(width*3/4,height,0,0);
						if(crop =='middle') obj = obj.crop(width*3/4,height,width/8,0);
						if(crop =='top') obj = obj.crop(width*3/4,height,width/4,0);
					}
					else if(v < 0.6) {
						if(crop =='top') obj = obj.crop(width,height*3/4,0,0);
						if(crop =='middle') obj = obj.crop(width,height*3/4,0,height/8);
						if(crop =='bottom') obj = obj.crop(width,height*3/4,0,height/4);
					}
			
					obj.resize(dist).write(formateFile, function(err) {        
	              if(err){
	              	
									sendJson(res,{error:'resize'});
									return;
								}
								height = Math.floor(height*dist/width);

								computeAndGen(res,dist,height,reqParam,formateFile)
				 });
				}else{
					computeAndGen(res,width,height,reqParam,theFile)
				}
				
			})
		}else if(fileType == 'mp4'){
			var picPath = theFile.replace('mp4','gif')
			mp4ToGif(res,reqParam,theFile,picPath)
		}else{
			sendJson(res,{error:'fileType'});
			return;
		}

  });
})

//mp4转gif
function mp4ToGif(res,reqParam,videoPath,picPath){
	var startTime=reqParam.startTime
	var duration=reqParam.duration
	var crop=reqParam.crop
	
	if(!startTime)startTime=0
	if(!duration)duration=3
	
	var probe = "ffprobe -i " + videoPath 
	+ " -print_format json -show_streams  -v 0" ;
	exec(probe, function(err,stdout,stderr){
		 if(err){
			sendJson(res,{error:'probe'});
			return;
		}
		var info = JSON.parse(stdout)
		var width = 300
		var height = 300
		for(var i=0;i<info.streams.length;i++){
			if(info.streams[i].width){
				width = info.streams[i].width
				height = info.streams[i].height
				break;
			}
		}

		
		var cropStr = '';
		var v = width/height;
		var w = 400
		var h = 300
		if(v>1.4) cropStr= getCutCrop(crop[0],'horizon') + ' -s 400*300'
		else if(v < 0.6) {
			cropStr= getCutCrop(crop[0],'vertical') + ' -s 300*400'
			w = 300;h=400;
		}
		else if(v > 1) {
			cropStr='-vf scale=400:-1'
			h=Math.floor(height * 400/width)
		}
		else {
			cropStr='-vf scale=300:-1'
			w = 300
			h=Math.floor(height * 300/width)
		}
	
		var cmdStr = "ffmpeg -ss " + startTime + " -t " + duration + " -i " + videoPath 
		+ " "+cropStr+" -b 568k -r 3 -pix_fmt rgb24 -y " + picPath;
		exec(cmdStr, function(err,stdout,stderr){
			  	computeAndGen(res,w,h,reqParam,picPath)
		})
	})
}

function getCutCrop(crop,direct){
	if(crop =='bottom' && direct=='horizon') return '-vf crop=iw*3/4:ih:0:0';
	if(crop =='middle' && direct=='horizon') return '-vf crop=iw*3/4:ih:iw*1/8:0';
	if(crop =='top' && direct=='horizon') return '-vf crop=iw*3/4:ih:iw/4:0';
	if(crop =='top' && direct=='vertical') return '-vf crop=iw:ih*3/4:0:0';
	if(crop =='middle' && direct=='vertical') return '-vf crop=iw:ih*3/4:0:ih/8';
	if(crop =='bottom' && direct=='vertical') return '-vf crop=iw:ih*3/4:0:ih/4';
	return '';
	
}

function computeAndGen(res,width,height,reqParam,theFile){
	if(height < 100){
				sendJson(res,{error:'height error'});
				return;
			}
		var msg = reqParam.msg;
		var fontSize = 26;
		if(reqParam.msg instanceof Array)msg=reqParam.msg[0]
		
		
		msg = formateMsg(width,height,msg,fontSize);
		
		var font = reqParam.font;
		var color = reqParam.color;
		var jumper = reqParam.jumper;
		var border = reqParam.border;
		var star = reqParam.star;
		var direct = reqParam.direct;
		
		var x=1,y=1;
		if(!direct) direct = 'South';
		if(!font || !config.fonts[font]){
			font = "tehei";
		}
		if(!color) color='black';
		var fileType = '.jpg';
		if(theFile.indexOf('.gif') >0) fileType = '.gif';
	
		var params = config[env +'Param'];
		
		var date = utils.getDateString(true) +"/"
		var folder = params.temPath + date
		
		utils.folderCheck(folder)
	
		var ttf = params.fontPath+font+'.ttf'
		var tmpFileName = utils.uuid() + fileType;
		
		var tmpFile =  folder+tmpFileName;
		
		var finalName = date + tmpFileName;
		var srcFile = theFile;
		
		if(jumper !='true' && star !='true' && border!='true')
			genText(res,srcFile,ttf,fontSize,x,y,msg,color,tmpFile,finalName,direct)
		else if(jumper !='true' && star !='true' && border=='true')
			strokeText(res,srcFile,ttf,fontSize,x,y,msg,color,tmpFile,finalName,direct)
		else{
			
			var  im = imageMagick(srcFile).size(function(err, value){
					
				genGif(res,value,srcFile,ttf,fontSize,x,y,msg,color,tmpFile,finalName,jumper,border,star,fileType,direct)
			})
			
			
		}
}

function formateMsg(width,height,msg,fontSize){
	var lines = msg.split("\r\n");

	if(lines.length > 1) return msg;

	var cols = Math.floor(width/(fontSize+2))
	var reg = new RegExp('(.{'+cols+'})','g')
	return msg.replace(reg,'$1\n')

	
}

function genGif(res,value,srcFile,ttf,fontSize,x,y,msg,fontColor,tmpFile,finalName,jumper,border,star,fileType,direct){

	var total = 0;		
	var tmpPngFile = 	tmpFile.substr(0,tmpFile.length - 4) 
	if(jumper =='true' && border=='true'){
		
		strokeTextAndWave(direct,value,ttf,fontSize,x,y,msg,fontColor,tmpPngFile+1,3,function(){total++; if(total==3)joinToGif(res,srcFile,tmpFile,finalName,fileType,tmpPngFile)})
		strokeTextAndWave(direct,value,ttf,fontSize,x,y,msg,fontColor,tmpPngFile+2,0,function(){total++; if(total==3)joinToGif(res,srcFile,tmpFile,finalName,fileType,tmpPngFile)})
		strokeTextAndWave(direct,value,ttf,fontSize,x,y,msg,fontColor,tmpPngFile+3,-3,function(){total++; if(total==3)joinToGif(res,srcFile,tmpFile,finalName,fileType,tmpPngFile)})
		
	}else if(jumper =='true'){
		waveText(direct,value,ttf,fontSize,x,y,msg,fontColor,tmpPngFile+1,3,function(){total++; if(total==3)joinToGif(res,srcFile,tmpFile,finalName,fileType,tmpPngFile)})
		waveText(direct,value,ttf,fontSize,x,y,msg,fontColor,tmpPngFile+2,0,function(){total++; if(total==3)joinToGif(res,srcFile,tmpFile,finalName,fileType,tmpPngFile)})
		waveText(direct,value,ttf,fontSize,x,y,msg,fontColor,tmpPngFile+3,-3,function(){total++; if(total==3)joinToGif(res,srcFile,tmpFile,finalName,fileType,tmpPngFile)})
	}
	
}

function joinToGif(res,srcFile,tmpFile,finalName,fileType,tmpPngFile){

	if(fileType == '.gif'){
		gm(srcFile).identify(function(err, value){
			var length = value.Scene.length;
			if(length == 1){
				onePageToGif(res,srcFile,tmpPngFile,finalName);
				return;
			}
			var cmdStr= " convert  "+srcFile
			for(var i=0;i<length;i++){
				cmdStr += " \\( -clone "+ i+ " "+tmpPngFile + (i%3+1)+".png -composite \\)  -swap "+i+" +delete "
			}
			cmdStr += tmpPngFile+'.gif'
			
			exec(cmdStr, function(err,stdout,stderr){
		  	if(err) {
		        sendJson(res,{error:'joinToGif error'});
		    } else {
		    	sendJson(res,{file:finalName.substr(0,finalName.length - 3)+'gif' }); 
		    }
		  })
			
		})
		
	}else{
		onePageToGif(res,srcFile,tmpPngFile,finalName);
	}

}

function onePageToGif(res,srcFile,tmpPngFile,finalName){
	var cmdStr= " convert  "+srcFile
       	+" \\( -clone 0 "+tmpPngFile+1+".png"+" -composite \\) "
        +" \\( -clone 0 "+tmpPngFile+2+".png"+" -composite \\) "
        +" \\( -clone 0 "+tmpPngFile+3+".png"+" -composite \\) "
        +" -delete 0 -set delay 10  " + tmpPngFile+'.gif'

	exec(cmdStr, function(err,stdout,stderr){
  	if(err) {
        sendJson(res,{error:'gif error'});
    } else {
    	sendJson(res,{file:finalName.substr(0,finalName.length - 3)+'gif'} ); 
    }
  })
  
}

function genText(res,file,ttf,fontSize,x,y,msg,fontColor,tmpFile,fileName,direct){
	var d=direct
	if(!d) d = 'North'
	imageMagick(file)    
        .font(ttf)          
        .fontSize(fontSize)
        .fill(fontColor)
        .drawText(x,y,msg,d)
        .quality(70)
        .write(tmpFile, function(err) {        
              if (!err){    
              	sendJson(res,{file:fileName});    
              }else{sendJson(res,{error:'drawText error'}); } });
}

function strokeText(res,file,ttf,fontSize,x,y,msg,fontColor,tmpFile,fileName,direct){
	var d=direct
	if(!d) d = 'North'
	var blurColor = config.colors[fontColor]
	imageMagick(file)    
        .font(ttf)
        .fontSize(fontSize)
        .fill(blurColor)
        .drawText(x+2,y+2,msg,d)
        .fill(blurColor)
        .drawText(x-2,y-2,msg,d)
        .fill(blurColor)
        .drawText(x-2,y+2,msg,d)
        .fill(blurColor)
        .drawText(x+2,y-2,msg,d)
        .fill(fontColor)
        .drawText(x,y,msg,d)
        .quality(70)
        .write(tmpFile, function(err) {        
              if (!err){   
              	sendJson(res,{file:fileName});      
              }else{sendJson(res,{error:'strokeText error'}); } });
	
}

function strokeTextAndWave(direct,value,ttf,fontSize,x,y,msg,fontColor,tmpFile,waveSize,callBack){
	
	var d=direct
	if(!d) d = 'North'
	
	var blurColor = config.colors[fontColor]
	imageMagick(value.width,value.height,'rgba(0,0,0,0)')
				.font(ttf)
        .fontSize(fontSize)
        .fill(blurColor)
        .drawText(x+2,y+2,msg,d)
        .fill(blurColor)
        .drawText(x-2,y-2,msg,d)
        .fill(blurColor)
        .drawText(x-2,y+2,msg,d)
        .fill(blurColor)
        .drawText(x+2,y-2,msg,d)
        .fill(fontColor)
        .drawText(x,y,msg,d)
        .wave(waveSize,100)
        .background('none')
        .quality(70)
        .write(tmpFile + '.png', function(err) {        
              if(callBack) callBack() });
	
}

function waveText(direct,im,ttf,fontSize,x,y,msg,fontColor,tmpFile,waveSize,callBack){  
	var d=direct
	if(!d) d = 'North' 
  imageMagick(value.width,value.height,'rgba(0,0,0,0)')
				.font(ttf)
        .fontSize(fontSize)
        .fill(fontColor)
        .drawText(x,y,msg,d)
        .wave(waveSize,100)
        .background('none')
        .quality(70)
        .write(tmpFile + '.png', function(err) {   
        	if(callBack) callBack()     
         });
	
}

function sendJson(res,obj){
	//res.writeHead(200, { "Content-Type": "application/json;charset=UTF-8" });
	if(obj && obj.error) console.log(JSON.stringify(obj))
	//res.send(JSON.stringify(obj)); 
	res.writeHead(200,{"Content-type":"text/html;charset=UTF-8"});
	res.end(JSON.stringify(obj));
}

module.exports = router;
